import time
import snap7
import logging
import threading
import pandas as pd
import numpy as np
import redis


def config_log():
    log = logging.getLogger()


class Storage:
    pass


class SSevenDataType:
    BOOL = 1
    BYTE = 1
    INT = 2
    WORD = 2
    DINT = 4
    DWORD = 4
    REAL = 4


class GetDataSSeven(threading.Thread):
    def __init__(self, address='127.0.0.1', rack: int = 0, solt: int = 1, port: int = 102):
        """

        :param address:IP地址
        :param rack: 机架号，0
        :param solt: 插槽号：1200/1500：0 others:1
        :param port: S7默认开放102端口
        """
        super(GetDataSSeven, self).__init__()
        self.address = address
        self.rack = rack
        self.solt = solt
        self.port = port
        self.s_seven_client = snap7.client.Client()
        self._storage = Storage()
        self.redis_client = None


    def connect(self):
        """
        建立连接
        :return:
        """
        if self.s_seven_client.get_connected():
            return
        else:
            try:
                self.s_seven_client.connect(self.address, self.rack, self.solt, self.port)
            except:
                pass

    def disconnect(self):
        """
        断开连接
        :return:
        """
        if self.s_seven_client.get_connected():
            self.s_seven_client.disconnect()

        else:
            return

    def load_file(self):
        pass

    def read_data(self, area, dbnumber, start, datatype, bit_index=0):
        """
        读取数据
        :param area: snap7.types.Areas.DB/M/PE(I)/PA(Q)
        :param dbnumber: 如果读db那么直接写db块号，读其他的默认为1
        :param start: 开始字节号
        :param size: 字节总数
        :param bit_index: 准备获取的bit
        :return: 字节数组
        """
        if self.s_seven_client.get_connected():
            if datatype == SSevenDataType.BOOL:
                return snap7.util.get_bool(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1,
                    bit_index)
            elif datatype == SSevenDataType.BYTE:
                return snap7.util.get_byte(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            elif datatype == SSevenDataType.INT:
                return snap7.util.get_int(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            elif datatype == SSevenDataType.WORD:
                return snap7.util.get_word(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            elif datatype == SSevenDataType.DINT:
                return snap7.util.get_dint(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            elif datatype == SSevenDataType.DWORD:
                return snap7.util.get_dword(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            elif datatype == SSevenDataType.REAL:
                return snap7.util.get_real(
                    self.s_seven_client.read_area(area=area, dbnumber=dbnumber, start=start, size=datatype), 1)
            else:
                return None
        else:
            raise Exception

    def get_once(self):
        self.connect()
        try:
            res = self.read_data(snap7.types.Areas.DB, 27, 0, SSevenDataType.BYTE)
            print(res)
        except:
            pass
        finally:
            self.disconnect()

    def get_data_forever(self, args):
        self.connect()
        self.redis_client = redis.StrictRedis(host='39.96.77.96', db=1)
        while True:
            try:
                # res = list(map(self.read_data, *args))
                # print(res)
                pass
            except Exception as e:
                self.disconnect()
                self.redis_client.close()
                self.redis_client = None
                time.sleep(3)
                self.connect()
                self.redis_client = redis.StrictRedis(host='39.96.77.96', db=1)
            else:
                pass
            time.sleep(1)

    def run(self) -> None:
        self.get_data_forever(self._storage)


if __name__ == '__main__':
    c = GetDataSSeven("192.168.8.11")
    c.start()
    c.join()


"""
args = tuple(zip(
            [snap7.types.Areas.DB, 27, 68, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 72, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 76, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 80, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 84, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 88, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 92, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 96, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 100, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 104, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 108, SSevenDataType.REAL],
            [snap7.types.Areas.DB, 27, 112, SSevenDataType.REAL]
        ))"""